home *** CD-ROM | disk | FTP | other *** search
Wrap
> Here are three ways to sum over a computed quantity: > > * Create a result tree fragment containing nodes whose value is the computed > number, and use sum(xx:node-set($rtf//value)) to do the summation, where > xx:node-set() is your vendor's extension function for converting an RTF to a > node-set > > * Use a recursive named template [this is the only standard XSLT 1.0 > solution] > > * Use the xalan extension function xalan:sum($nodes, xalan:expression(...)) > > I want to sum the "freespace", but sum(//disk/freespace) > > won't work because > > freespace is not a number due to the trailing "MB". The first of the above solutions requires inappropriate amount of memory and time. The third ties us to a proprietary (although one of the best) XSLT processor. The second is too-general, as one can achieve almost anything in XSLT with recursion. It would be almost equivalent to say: "Use arithmetic rules". Here's another, more practical way, since it uses a "library function" -- transformAndSum: http://sources.redhat.com/ml/xsl-list/2001-11/msg00831.html This is ***the*** general solution for all such problems belonging to this "transform and sum" class of problems... Having such a general solution available in pure XSLT shows that any "dynamic module" effort is very limited and therefore not applicable (== of any use) in the general cases. Re-Using the ready-made "transform and sum" function described in the above link gives us the following: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:func-transform="f:func-transform" exclude-result-prefixes="xsl func-transform" > <xsl:import href="transform-and-sum.xsl"/> <xsl:output method="text"/> <func-transform:func-transform/> <xsl:template match="/"> <xsl:call-template name="transform-and-sum"> <xsl:with-param name="pFuncTransform" select="document('')/*/func-transform:*[1]"/> <xsl:with-param name="pList" select="//freespace"/> </xsl:call-template> </xsl:template> <xsl:template match="func-transform:*"> <xsl:param name="arg" select="0"/> <xsl:value-of select="substring-before($arg, ' ')"/> </xsl:template> </xsl:stylesheet> When this transformation is applied on the following (your) source xml: <disks> <disk> <freespace>1235 MB</freespace> </disk> <disk> <freespace>40 MB</freespace> </disk> <disk> <freespace>75 MB</freespace> </disk> </disks> The result is: 1350 Hope this helped. Cheers, Dimitre Novatchev.